import MySQLdb
import redis
from config import settings



class Database:
    __db_instances = {}  # 类属性

    @classmethod  # 定义类方法
    def get_instance(cls, db_type = settings.DatabaseType.MYSQL):  # 类方法，创建单例模式每次创建都是返回同一个实例
        """cls就是传入的database类参数
        无论调用多少次都只有一个对象
        定义get_instance类方法，用来获取数据库对象的单例
        所谓的单例就是一个类只有一个实例，调用该方法每次获取到
        的都是同一个数据库实例,，type_默认为MYSQL类型，表示
        默认获取的是mysql的数据库实例
        """
        if db_type not in cls.__db_instances: # 只会构造一次实例，如果再次使用还使用这个实例
            # 如果不存在，就构造一个Database的实例对象
            cls.__db_instances[db_type] = cls(db_type)  # 实例化一个类对象,参数为db_type类型0为数据库，1为redis
        return cls.__db_instances[db_type]

    class Database:
        __db_instance = {}

        @classmethod
        def get_instance(cls, db_type=0):
            if db_type not in cls.__db_instance:
                cls.__db_instance[db_type] = cls()
            return cls.__db_instance[db_type]


    def __init__(self, db_type = settings.DatabaseType.MYSQL):  # 通过类名（）构造实例的时候自动调用构造函数
        """
        :param db_type: 数据库的类型，数据库的类型在DatabaseType中进行了定义
        默认为MYSQL类型，表示创建mysql类型的数据库实例
        """
        self.__db_type = db_type   # 对象属性
        self.__db = self.__get_database()
        self.__cursors = {}

    def __get_database(self):
        db = None
        # 根据类型字段，来创建对应的数据库实例
        if self.__db_type == settings.DatabaseType.MYSQL:
            try:
                db = MySQLdb.connect(settings.DATABASE["mysql"]["host"],
                                     settings.DATABASE["mysql"]["username"],
                                     settings.DATABASE["mysql"]["password"],
                                     settings.DATABASE["mysql"]["db"],
                                     charset="utf8"
                                     )
            except:
                db = None
        elif self.__db_type == settings.DatabaseType.REDIS:
            db = redis.Redis(host=settings.DATABASE["reids"]["host"],
                                  port=settings.DATABASE["reids"]["port"],
                                  db= settings.DATABASE["reids"]["db"])
        return db

    def query(self, ql, *args):  # 查询
        """
        :param ql: 表示查询的语句
        :param args: 表示查询语句中的参数
        :return: 查询的数据
        """
        data = None
        if self.__db_type == settings.DatabaseType.MYSQL:
            if settings.DatabaseType.MYSQL not in self.__cursors:
               self.__cursors[settings.DatabaseType.MYSQL] = self.__db.cursor()

            if not args:  # 无参数的情况
               self.__cursors[settings.DatabaseType.MYSQL].execute(ql)
            else:
                self.__cursors[settings.DatabaseType.MYSQL].executemany(ql, args)

            data = self.__cursors[settings.DatabaseType.MYSQL].fetchall() # 获取单行或者多行都行
        return data

    def insert(self, ql, *args):
        """
        :param ql: 表示插入的语句
        :param args: 表示插入语句的参数
        :return:
        """
        if self.__db_type == settings.DatabaseType.MYSQL:
            if settings.DatabaseType.MYSQL not in self.__cursors:
                self.__cursors[settings.DatabaseType.MYSQL] = self.__db.cursor()
            if not args:
                self.__cursors[settings.DatabaseType.MYSQL].execute(ql)
            else:
                self.__cursors[settings.DatabaseType.MYSQL].executemany(ql, args)
            self.__db.commit()



